﻿using Fuse8.ContentManagementFramework.Administration.Attributes;
using Fuse8.ContentManagementFramework.BizFacade;
using Fuse8.ContentManagementFramework.BizFacade.Services;
using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Domain.Bases;
using Fuse8.ContentManagementFramework.Domain.Special;
using Fuse8.ContentManagementFramework.SystemFacade.Utilities;
using Fuse8.DomainFramework.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;

namespace Fuse8.ContentManagementFramework.Administration.Models
{
    public static class CmsAdminPageModelExtensions
    {
        public static CmsPage ConvertToPage(this CmsAdminPageModel model, bool isEdit = true)
        {
            Guard.ArgumentNotNull(model, "model");

            var result = new CmsPage
                             {
                                 Id = model.Id,
                                 PageName = model.PageName,
                                 PageUrl = model.PageUrl ?? "/", // default url is "/"
                                 ParentPageId = model.ParentPageId,
                                 TemplateId = model.TemplateId,
                                 PageTypeKey = model.PageTypeKey,
                                 IsVisible = model.IsVisible,
                                 UseFileCache = model.UseFileCache,
                                 SiteGroupId = model.SiteGroupId,
                                 SiteId = model.SiteId,
                                 PageTitle = model.PageTitle,
                                 PageKeywords = model.PageKeywords,
                                 PageDescription = model.PageDescription,
                                 WorkflowId = model.WorkflowId,
                                 IsPublished = model.IsPublished,
                                 PublishStartDate = model.PublishStartDate,
                                 PublishEndDate = model.PublishEndDate,
                                 PageBehaviourTypeKey = (int)model.BehaviourPageType,
                                 PageKey = model.PageKey,
                                 RedirectSetting = new CmsRedirectPageSetting()
                                                       {
                                                           PublicPageIdToRedirect = model.RedirectPageId,
                                                           Type = model.RedirectType,
                                                           UrlToRedirect = model.RedirectUrl,
                                                           OpenInNewWindow = model.RedirectOpenInNewWindow
                                                       }
                             };

            SiteAwareEntityObjectMediator.SetSiteEntityByCategory(result, SiteAwareCategory.Site);

            if (model.WorkflowId.HasValue)
            {
                result.Workflow = new CmsWorkflow
                {
                    Id = model.WorkflowId.Value,
                    ApproveDateDeadline = model.DateApprovalDeadline,
                    ReviewDateDeadline = model.DateReviewDeadline
                };
            }

            return result;
        }
    }

    [Serializable]
    public class CmsAdminPageModel : CmsSiteAwareModel
    {
        #region Fields

        private int? _templateId;

        private IEnumerable<dynamic> _templateList;

        #endregion Fields

        #region Properties

        public int LatestPageId { get; set; }

        public int? ParentPageId { get; set; }

        public string ParentPageName { get; set; }

        [GlobalizedRequired("Please enter page title", "cms_Pages")]
        public string PageName { get; set; }

        public string PageUrl { get; set; }

        public CmsPageBehaviourTypeKind BehaviourPageType { get; set; }

        public bool IsVisible { get; set; }

        public bool UseFileCache { get; set; }

        public string PageTitle { get; set; }

        public string PageKeywords { get; set; }

        public string PageDescription { get; set; }

        public bool IsPublished { get; set; }

        public DateTime? PublishStartDate { get; set; }

        public DateTime? PublishEndDate { get; set; }

        public DateTime DatePublished { get; set; }

        public bool IsLatestRevision { get; set; }

        public Guid? WorkflowId { get; set; }

        public string WorkflowNotes { get; set; }

        public int PageLocation { get; set; }

        //Managed cursors
        public string Preview { get; set; }

        public string Save { get; set; }

        public string Apply { get; set; }

        public bool IsSaveConfirmation { get; set; }

        public string MakeNewRevision { get; set; }

        public string Workflow { get; set; }

        //End of managed cursors

        public DateTime? DateApprovalDeadline { get; set; }

        public DateTime? DateReviewDeadline { get; set; }

        public int WorkflowTransitionId { get; set; }

        public bool SendNotification { get; set; }

        public int? AssignedUser { get; set; }

        public int PublicPageId { get; set; }

        public string PageKey { get; set; }

        public int TemplateId
        {
            get
            {
                if (!_templateId.HasValue)
                {
                    if (TemplateList is IEnumerable<string>)
                    {
                        _templateId = int.Parse(TemplateList.Cast<string>().SingleOrDefault());
                    }
                }

                return _templateId.GetValueOrDefault(0);
            }
            set
            {
                _templateId = value;
            }
        }

        public int PageTypeKey { get; set; }

        public int? RedirectPageId { get; set; }

        public string RedirectUrl { get; set; }

        public bool RedirectOpenInNewWindow { get; set; }

        public PageRedirectKind RedirectType { get; set; }

        public bool ReirectPermanent { get; set; }

        public CmsEntityMetaInformation MetaInformation { get; protected set; }

        public IList<CmsEntityMetaModel> Metas { get; set; }

        public SelectList PageTypeList { get; set; }

        public SelectList RedirectTypes
        {
            get
            {
                return new SelectList(
                EnumUtility<PageRedirectKind>.GetNamesAndDescriptions(true),
                "Key", "Value", RedirectType);
            }
        }

        public IEnumerable<dynamic> TemplateList
        {
            get
            {
                if (_templateList == null)
                {
                    var templateService = new CmsTemplateService();

                    var allTemplates = templateService.FindAll();

                    allTemplates = new CmsTemplate[]
                    {
                        new CmsTemplate
                        {
                            Id = 0,
                            TemplateTypeKey = 0,
                            IsDefault = !allTemplates.Any()
                        }
                    }.Concat(allTemplates);

                    var templateToSelect = _templateId.HasValue && (_templateId.Value > 0) ?
                        _templateId.Value :
                        templateService.DefaultTemplate.Id;

                    _templateList = new SelectList(
                        allTemplates.Select(
                            p => new
                            {
                                Id = p.Id,
                                Title = p.IsDefault ? string.Format("{0} - default", p.TemplateName) : p.TemplateName,
                                IsDefault = p.IsDefault
                            }),
                        "Id", "Title", templateToSelect);
                }

                return _templateList;
            }
            set
            {
                _templateList = value;
            }
        }

        public IEnumerable<dynamic> TemplateRegionList { get; set; }

        public string RedirectPageName { get; set; }

        #endregion Properties

        #region Constructor

        public CmsAdminPageModel()
        { }

        public CmsAdminPageModel(CmsAdminPageModel notValidModel)
            : this()
        {
            Guard.ArgumentNotNull(notValidModel, "notValidModel");

            Id = notValidModel.Id;
            ParentPageId = notValidModel.ParentPageId;
            ParentPageName = notValidModel.ParentPageName;
            PageName = notValidModel.PageName;
            PageUrl = notValidModel.PageUrl;
            IsVisible = notValidModel.IsVisible;
            UseFileCache = notValidModel.UseFileCache;
            PageTitle = notValidModel.PageTitle;
            PageKeywords = notValidModel.PageKeywords;
            PageDescription = notValidModel.PageDescription;
            SiteGroupId = notValidModel.SiteGroupId;
            SiteId = notValidModel.SiteId;
            DatePublished = notValidModel.DatePublished;
            IsLatestRevision = notValidModel.IsLatestRevision;
            WorkflowId = notValidModel.WorkflowId;
            IsPublished = notValidModel.IsPublished;
            PublishStartDate = notValidModel.PublishStartDate;
            PublishEndDate = notValidModel.PublishEndDate;
            DateApprovalDeadline = notValidModel.DateApprovalDeadline;
            DateReviewDeadline = notValidModel.DateReviewDeadline;
            PageLocation = notValidModel.PageLocation;
            TemplateId = notValidModel.TemplateId;
            BehaviourPageType = notValidModel.BehaviourPageType;
            RedirectOpenInNewWindow = notValidModel.RedirectOpenInNewWindow;
            RedirectPageId = notValidModel.RedirectPageId;
            RedirectPageName = notValidModel.RedirectPageName;
            RedirectType = notValidModel.RedirectType;
            RedirectUrl = notValidModel.RedirectUrl;
            PageTypeList = new SelectList(
                EnumUtility<CmsPageBehaviourTypeKind>.GetNamesAndDescriptions(true),
                "Key", "Value", (int)BehaviourPageType);
        }

        public CmsAdminPageModel(CmsPage page, int? currentTemplateRegionId = null)
            : this()
        {
            Guard.ArgumentNotNull(page, "page");

            Id = page.Id;
            ParentPageId = page.ParentPageId;
            ParentPageName = page.ParentPageName;
            PageName = page.PageName;
            PageUrl = page.PageUrl;
            IsVisible = page.IsVisible;
            UseFileCache = page.UseFileCache;
            PageTitle = page.PageTitle;
            PageKeywords = page.PageKeywords;
            PageDescription = page.PageDescription;
            SiteGroupId = page.SiteGroupId;
            SiteId = page.SiteId;
            DatePublished = page.DatePublished;
            IsLatestRevision = page.IsLatestRevision.GetValueOrDefault(false);
            WorkflowId = page.WorkflowId;
            PublicPageId = page.PublicPageId;
            PageKey = page.PageKey;

            if (WorkflowId.HasValue)
            {
                DateApprovalDeadline = page.Workflow.ApproveDateDeadline;
                DateReviewDeadline = page.Workflow.ReviewDateDeadline;
            }

            IsPublished = page.IsPublished;
            PublishStartDate = page.PublishStartDate;
            PublishEndDate = page.PublishEndDate;
            PageLocation = page.Id;
            TemplateId = page.TemplateId;
            BehaviourPageType = page.BehaviourPageType;
            PageTypeList = new SelectList(
                EnumUtility<CmsPageBehaviourTypeKind>.GetNamesAndDescriptions(true),
                "Key", "Value", BehaviourPageType);

            if (page.BehaviourPageType == CmsPageBehaviourTypeKind.Redirect)
            {
                var settings = page.RedirectSetting;
                RedirectOpenInNewWindow = settings.OpenInNewWindow;
                RedirectType = settings.Type;
                RedirectUrl = settings.UrlToRedirect;
                RedirectPageId = settings.PublicPageIdToRedirect;
                if (settings.PublicPageIdToRedirect.HasValue)
                {
                    var redirecPage = new CmsPageService().FindByPublicId(settings.PublicPageIdToRedirect.Value);
                    if (redirecPage != null)
                    {
                        RedirectPageName = redirecPage.PageName;
                    }
                }
            }

            MetaInformation = page.EntityMetaInformation;

            if (page.TemplateId > 0)
            {
                PageTypeKey = (int)page.Template.TemplateType.Convert();
                TemplateRegionList = DefineTemplateRegions(page.Template, currentTemplateRegionId.GetValueOrDefault(0));
            }
        }

        #endregion Constructor

        #region Methods

        private SelectList DefineTemplateRegions(CmsTemplate template, int currentTemplateId)
        {
            SelectList result = null;

            if (template.TemplateRegions.Any())
            {
                var data = template.TemplateRegions.Select(
                            p => new
                            {
                                Id = p.Id,
                                Title = p.TemplateRegionName
                            });

                var regionToSelect = currentTemplateId > 0 ?
                    currentTemplateId :
                    data.FirstOrDefault().Id;

                result = new SelectList(data, "Id", "Title", regionToSelect);
            }

            return result;
        }

        #endregion Methods
    }
}